﻿/**	@file		rect.hpp
 *	@date		(2007-02-10 23:08:03)/(2012-01-02 00:14:05)
 *-----------------------------------------------------------------------------
 *	@version	1.0.5.6
 *	@author		Nick Shallery	(nicknide@gmail.com)
 *	@copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/

#if			!defined(__LOLIX__SOLA__RECT__K_IN_G__)
#define		__LOLIX__SOLA__RECT__K_IN_G__
//==============================================================================
//--------------------------------------------------------------------------

#if			!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)
	#include	"../lolix_macro.h"
#endif	//	!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)

#if			!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
	#include	"../lolix_type.h"
#endif	//	!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)

#if			!defined(__LOLIX__TOY__L_X_ASSERT_NICK__K_IN_G__)
	#include	"../toy/lx_assert.h"
#endif	//	!defined(__LOLIX__TOY__L_X_ASSERT_NICK__K_IN_G__)

namespace lolix{namespace sola{
	template<typename _Ty>					class rect;
	template<typename _Tl, typename _Tr>	void trans_rect(rect<_Tl>& tl, const rect<_Tr>& tr);

	template<typename _Ty>
	class rect
	{
	public:
		_Ty left;
		_Ty bottom;
		_Ty right;
		_Ty top;

		LOLIX_INLINE_CALL rect<_Ty>(void){}
		LOLIX_INLINE_CALL rect<_Ty>(_Ty l, _Ty r, _Ty b, _Ty t)
			: left(l), right(r), top(t), bottom(b)
			{}
		template<typename _Tx>
		LOLIX_INLINE_CALL explicit rect<_Ty>(rect<_Tx> const& r)
			: left(static_cast<_Ty>(r.left))
			, right(static_cast<_Ty>(r.right))
			, top(static_cast<_Ty>(r.top))
			, bottom(static_cast<_Ty>(r.bottom))
			{}

		LOLIX_INLINE_CALL _Ty width(void)const{return right - left;}
		LOLIX_INLINE_CALL _Ty heigh(void)const{return top - bottom;}

		template<typename _To>
		LOLIX_INLINE_CALL rect<_Ty>& operator = (const rect<_To> rc)
			{
			left = rc.left;
			top = rc.top;
			bottom = rc.bottom;
			right = rc.right;
			return *this;
			}

		LOLIX_INLINE_CALL bool operator == (rect<_Ty> const& o)const
			{ return this->left == o.left && this->bottom == o.bottom && this->right == o.right && this->top == o.top; }

		LOLIX_INLINE_CALL bool operator != (rect<_Ty> const& o)const
			{ return !this->operator == (o); }

		//===========================================================================
		//	两个矩形相乘
		//---------------------------------------------------------------------------
		//	o		[i ] :	目标矩形
		//---------------------------------------------------------------------------
		//	a *= b
		//		将 a 目前的长度， 根据当前单位矩形计算， 而换算到 b 的空间中去
		//===========================================================================
		LOLIX_INLINE_CALL rect<_Ty>& trans_to(const rect<_Ty>& o)
			{
			trans_rect(*this, o);
			return *this;
			}
	};

	template<typename _Tl, typename _Tr>
	LOLIX_INLINE_CALL void trans_rect(rect<_Tl>& tl, const rect<_Tr>& tr)
		{
		//	必须至少有一个类型是浮点类型
		STATIC_ASSERT((type::type_equal<_Tl, float>::value
			|| type::type_equal<_Tl, double>::value
			|| type::type_equal<_Tr, float>::value
			|| type::type_equal<_Tr, double>::value
			));
		typedef typename type::type_choise<(type::type_equal<_Tl, double>::value || type::type_equal<_Tr, double>::value), double, float>::type result_type;
		const result_type obj_w = (result_type)tr.width();
		tl.left *= obj_w;
		tl.right *= obj_w;
		tl.left += tr.left;
		tl.right += tr.left;

		const result_type obj_h = (result_type)tr.heigh();
		tl.top *= obj_h;
		tl.bottom *= obj_h;
		tl.top += tr.bottom;
		tl.bottom += tr.bottom;
		}
}}



//--------------------------------------------------------------------------
//==============================================================================
#endif	//	!defined(__LOLIX__SOLA__RECT__K_IN_G__)
